/*
 *  * Copyright (C) 2021 Huawei Device Co., Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package io.github.lizhangqu.sample;

import io.github.lizhangqu.coreprogress.ProgressHelper;
import io.github.lizhangqu.coreprogress.ProgressUIListener;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ProgressBar;
import ohos.agp.components.Text;
import ohos.app.Environment;
import ohos.bundle.IBundleManager;
import ohos.security.SystemPermission;
import okhttp3.OkHttpClient;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

import java.io.File;
import java.io.IOException;

/**
 * Main ability
 */
public class MainAbility extends Ability {
    private Button upload;
    private Button download;
    private Text uploadInfo;
    private Text downloadInfo;
    private ProgressBar uploadProgress;
    private ProgressBar downloadProgeress;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initView();
    }

    @Override
    protected void onActive() {
        super.onActive();
        checkStoragePermission();
    }

    private void initView() {
        uploadProgress = (ProgressBar) findComponentById(ResourceTable.Id_upload_progress);
        downloadProgeress = (ProgressBar) findComponentById(ResourceTable.Id_download_progress);

        uploadInfo = (Text) findComponentById(ResourceTable.Id_upload_info);
        downloadInfo = (Text) findComponentById(ResourceTable.Id_download_info);

        upload = (Button) findComponentById(ResourceTable.Id_upload);
        download = (Button) findComponentById(ResourceTable.Id_download);
        upload.setClickedListener(
                new Component.ClickedListener() {
                    @Override
                    public void onClick(Component v) {
                        upload();
                    }
                });
        download.setClickedListener(
                new Component.ClickedListener() {
                    @Override
                    public void onClick(Component v) {
                        download();
                    }
                });
    }

    private void upload() {
        uploadInfo.setText("start upload");
        String path = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
        File outFile = new File(path + "/temp.mp4");
        String url = "https://v2.convertapi.com/upload";

        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        builder.url(url);

        MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
        bodyBuilder.addFormDataPart(
                "test", outFile.getName(), RequestBody.create(outFile, MediaType.parse("video/mp4")));
        MultipartBody build = bodyBuilder.build();

        RequestBody requestBody =
                ProgressHelper.withProgress(
                        build,
                        new ProgressUIListener() {
                            // If you don't need this method, don't override this method.
                            // It isn't an abstract method, just an empty method.
                            @Override
                            public void onUIProgressStart(long totalBytes) {
                                super.onUIProgressStart(totalBytes);
                                LogUtil.error("TAG", "onUIProgressStart:" + totalBytes);
                            }

                            @Override
                            public void onUIProgressChanged(
                                    long numBytes, long totalBytes, float percent, float speed) {
                                LogUtil.error("TAG", "=============start===============");
                                LogUtil.error("TAG", "numBytes:" + numBytes);
                                LogUtil.error("TAG", "totalBytes:" + totalBytes);
                                LogUtil.error("TAG", "percent:" + percent);
                                LogUtil.error("TAG", "speed:" + speed);
                                LogUtil.error("TAG", "============= end ===============");
                                uploadProgress.setProgressValue((int) ((numBytes * 100) / totalBytes));
                                uploadInfo.setText(
                                        "numBytes:"
                                                + numBytes
                                                + " bytes totalBytes:"
                                                + totalBytes
                                                + " bytes percent:"
                                                + percent * 100
                                                + " % speed:"
                                                + speed * 1000 / 1024 / 1024
                                                + "  MB/s");
                            }

                            // if you don't need this method, don't override this method.
                            // It isn't an abstract method, just an empty method.
                            @Override
                            public void onUIProgressFinish() {
                                super.onUIProgressFinish();
                                LogUtil.error("TAG", "onUIProgressFinish:");
                            }
                        });
        builder.post(requestBody);

        Call call = okHttpClient.newCall(builder.build());
        call.enqueue(
                new Callback() {
                    @Override
                    public void onFailure(Call call, IOException exception) {
                        LogUtil.error("TAG", "=============onFailure===============" + exception.getMessage());
                        exception.printStackTrace();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        LogUtil.error("TAG", "=============onResponse===============");
                        LogUtil.error("TAG", "request headers:" + response.request().headers());
                        LogUtil.error("TAG", "response headers:" + response.headers());
                    }
                });
    }

    private void download() {
        downloadInfo.setText("start download");
        String url = "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4";

        OkHttpClient okHttpClient = new OkHttpClient();
        Request.Builder builder = new Request.Builder();
        builder.url(url);
        builder.get();
        Call call = okHttpClient.newCall(builder.build());
        LogUtil.error("TAG", "url : " + url);
        call.enqueue(
                new Callback() {
                    @Override
                    public void onFailure(Call call, IOException exception) {
                        LogUtil.error("TAG", "====onFailure======== e.getMessage() : " + exception.getMessage());
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        LogUtil.error("TAG", "=============onResponse===============");
                        LogUtil.error("TAG", "response length:" + response.body().contentLength());
                        LogUtil.error("TAG", "Content-Length: " + response.header("Content-Length"));

                        ResponseBody responseBody =
                                ProgressHelper.withProgress(
                                        response.body(),
                                        new ProgressUIListener() {
                                            // if you don't need this method, don't override this methd.
                                            // It isn't an abstract method, just an empty method.
                                            @Override
                                            public void onUIProgressStart(long totalBytes) {
                                                super.onUIProgressStart(totalBytes);
                                                LogUtil.error("TAG", "onUIProgressStart:" + totalBytes);
                                                downloadInfo.setText("onUIProgressStart:" + totalBytes);
                                            }

                                            @Override
                                            public void onUIProgressChanged(
                                                    long numBytes, long totalBytes, float percent, float speed) {
                                                LogUtil.error("TAG", "=============start===============");
                                                LogUtil.error(
                                                        "TAG",
                                                        "onUIProgressChanged  totalBytes : "
                                                                + totalBytes
                                                                + "  numBytes : "
                                                                + numBytes
                                                                + "  percent : "
                                                                + percent
                                                                + "  fp : "
                                                                + (numBytes * 100) / totalBytes
                                                                + "  speed : "
                                                                + speed);

                                                downloadProgeress.setProgressValue(
                                                        (int) ((numBytes * 100) / totalBytes));
                                                downloadInfo.setText(
                                                        "numBytes:"
                                                                + numBytes
                                                                + " bytes totalBytes:"
                                                                + totalBytes
                                                                + " bytes percent:"
                                                                + percent * 100
                                                                + " % speed:"
                                                                + speed * 1000 / 1024 / 1024
                                                                + "  MB/s");
                                            }
                                            // If you don't need this method, don't override this method.
                                            // It isn't an abstract method, just an empty method.
                                            @Override
                                            public void onUIProgressFinish() {
                                                super.onUIProgressFinish();
                                                LogUtil.error("TAG", "onUIProgressFinish");
                                            }
                                        });

                        BufferedSource source = responseBody.source();
                        String path = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
                        File outFile = new File(path + "/temp.mp4");
                        outFile.delete();
                        outFile.getParentFile().mkdirs();
                        outFile.createNewFile();

                        BufferedSink sink = Okio.buffer(Okio.sink(outFile));
                        source.readAll(sink);
                        sink.flush();
                        source.close();
                    }
                });
    }

    private void checkStoragePermission() {
        if (verifySelfPermission(SystemPermission.WRITE_USER_STORAGE) == IBundleManager.PERMISSION_GRANTED) {
            LogUtil.debug("Tag ", "verifySelfPermission : PERMISSION_GRANTED");
        } else {
            requestPermissionsFromUser(new String[] {SystemPermission.WRITE_USER_STORAGE}, 100);
        }
    }
}
